﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ObviousCode.UI.Aspect.PluginLibrary.Interfaces;
using ObviousCode.Aspect.PluginLibrary.Interfaces;
using ObviousCode.UI.Aspect.PluginLibrary;
using ObviousCode.Common.Utils.Library.Exceptions;

namespace ObviousCode.Aspect.PluginLibrary
{
    public class SurfaceItemDescriptorStore : IEnumerable<SurfaceItemDescriptor>
    {
        Dictionary<string, SurfaceItemDescriptor> _store;

        public SurfaceItemDescriptorStore()
        {
            _store = new Dictionary<string, SurfaceItemDescriptor>();
        }

        public SurfaceItemDescriptor AddDescriptor(string key, IAspectItemFactory factory)
        {
            return AddDescriptor(key, key, new ChartObjectImages(), new BasicTheme(), factory);
        }

        public SurfaceItemDescriptor AddDescriptor(string key, string description, IAspectItemFactory factory)
        {
            return AddDescriptor(key, description, new ChartObjectImages(), new BasicTheme(), factory);
        }

        public SurfaceItemDescriptor AddDescriptor(string key, string description, ChartObjectImages images, IAspectItemFactory factory)
        {
            return AddDescriptor(key, description, images, new BasicTheme(), factory);
        }

        public SurfaceItemDescriptor AddDescriptor(string key, string description, ChartObjectImages images, IUITheme theme, IAspectItemFactory factory)
        {
            SurfaceItemDescriptor descriptor = new SurfaceItemDescriptor(key, description, images, theme, factory);
            _store[key] = descriptor;

            return descriptor;
        }

        public IEnumerable<string> Keys
        {
            get
            {
                return _store.Keys;
            }
        }

        public SurfaceItemDescriptor this[string key]
        {
            get
            {
                if (!_store.ContainsKey(key)) ExceptionBuilder.Format("Descriptor Store does not contain key \"{0}\"", key);

                return _store[key];
            }    
            set
            {
                if (value == null || string.IsNullOrEmpty(key)) new InvalidOperationException();
                _store[key] = value;
            }
        }

        internal bool ContainsKey(string key)
        {
            return _store.ContainsKey(key);
        }

        public SurfaceItemDescriptor For(Type type)
        {
            if (!(typeof(IAspectItem).IsAssignableFrom(type))) ExceptionBuilder.Format("{0} does not implement IAspectItem", type);

            return _store.Values.Where(d => d.Factory.InstanceType == type).FirstOrDefault();
        }

        #region IEnumerable<SurfaceItemDescriptor> Members

        public IEnumerator<SurfaceItemDescriptor> GetEnumerator()
        {
            foreach (SurfaceItemDescriptor descriptor in _store.Values)
            {
                yield return descriptor;
            }
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        #endregion
    }
}
